package com.imooc.user.client;

import com.alibaba.fastjson.JSON;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.imooc.thrift.user.dto.UserDTO;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

/**
 * @author LiJian
 * @date 2022/10/24
 */
public abstract class LoginFilter implements Filter {

    private static Cache<String, UserDTO> cache =
            CacheBuilder.newBuilder().maximumSize(10000)
                    .expireAfterWrite(3, TimeUnit.MINUTES).build();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String token = request.getParameter("token");
        if (StringUtils.isBlank(token)) {
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if ("token".equals(cookie.getName())) {
                        token = cookie.getValue();
                    }
                }
            }
        }
        UserDTO userDTO = null;
        if (StringUtils.isNotBlank(token)) {
            // 从缓存中拿
            userDTO = cache.getIfPresent(token);
            if (userDTO == null) {
                userDTO = requestUserInfo(token);
                if(userDTO!=null){
                    cache.put(token,userDTO);
                }
            }
        }
        if (userDTO == null) {
            response.sendRedirect("http://192.168.0.241:30000/user/login");
            return;
        }
        login(request, response, userDTO);
        filterChain.doFilter(request, response);
    }

    protected abstract void login(HttpServletRequest request, HttpServletResponse response, UserDTO userDTO);

    private static UserDTO requestUserInfo(String token) {
        String url = "http://192.168.0.241:30000/user/authentication";
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("token", token);
        StringBuilder sb = new StringBuilder();
        try {
            CloseableHttpResponse response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                throw new RuntimeException("request user info failed!StatusLine:" + response.getStatusLine());
            }
            try (InputStream inputStream = response.getEntity().getContent();) {
                byte[] tmp = new byte[1024];
                int len = 0;
                while ((len = inputStream.read(tmp)) > 0) {
                    sb.append(new String(tmp, 0, len));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        UserDTO userDTO = JSON.parseObject(sb.toString(), UserDTO.class);
        return userDTO;
    }

    public static void main(String[] args) {
        UserDTO userDTO = requestUserInfo("3njcup7bpgqfufv2v1rmb25mdqfihlvh");
        System.out.println(111);
    }

    @Override
    public void destroy() {

    }
}
